์ ํ๋ธ ์ธ๋ค์ผ์ ๋ง๋ค๊ธฐ ์ํด ๋์์์์ ์ธ๋งํ ์ด๋ฏธ์ง๋ฅผ 4๊ฐ ์ถ์ถํ๊ฒ ์ต๋๋ค. ๋จผ์ , ๋์์์ ๋ก๋ํ๊ณ ํ๋ ์์ ์ถ์ถํ๊ฒ ์ต๋๋ค.
pythonfrom moviepy.editor import VideoFileClip
import matplotlib.pyplot as plt
# Load the video file
video_path = '/mnt/data/IMG_2091.MOV'
clip = VideoFileClip(video_path)
# Get the duration of the video in seconds
duration = clip.duration
# Generate 4 timestamps at which to capture frames for thumbnails
timestamps = [duration * i / 5 for i in range(1, 5)]
# Extract frames at the timestamps
frames = [clip.get_frame(t) for t in timestamps]
# Display the frames
fig, axes = plt.subplots(1, 4, figsize=(20, 5))
for ax, frame, t in zip(axes, frames, timestamps):
ax.imshow(frame)
ax.axis('off')
ax.set_title(f"{t:.2f}s")
plt.show()
์์ ์ด๋ฏธ์ง๋ ๋์์์์ ์ถ์ถํ 4๊ฐ์ ํ๋ ์์ ๋๋ค. ๊ฐ๊ฐ์ ํ๋ ์์ ๋์์์ ๋ค๋ฅธ ์์ ์์ ์บก์ฒ๋์์ต๋๋ค. ์ด ์ค์์ ์ด๋ค ์ด๋ฏธ์ง๋ฅผ ์ ํ๋ธ ์ธ๋ค์ผ๋ก ์ฌ์ฉํ๊ณ ์ถ์ผ์ ๊ฐ์?
์ธ๋ค์ผ์ ์ฌ์ฉํ ํ์ดํ์ ๋์์์ ๋ด์ฉ, ๋ชฉ์ , ๋์ ์์ฒญ์ ๋ฑ์ ๊ณ ๋ คํ์ฌ ๊ฒฐ์ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ค์์ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ์ ์์ ๋๋ค:
๋ง์ฝ ๋์์์ ์ฃผ์ ๋ ๋ชฉ์ ์ ์๋ ค์ฃผ์๋ฉด, ๋ ๊ตฌ์ฒด์ ์ธ ์ ์์ ๋๋ฆด ์ ์์ต๋๋ค.
๋ฌผ๋ก ์ด์ฃ . ๊ทธ๋ฌ๋ ๋์์์ ๋ด์ฉ์ ํ์ธํ ์ ์๊ธฐ ๋๋ฌธ์, ๋์์์ ์ฃผ์ ๋ ๋ชฉ์ ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ฃผ์๋ฉด ๋ ์ ํฉํ ์ ๋ชฉ์ ์ ์ํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ๋์์์ด ์ด๋ค ๋ด์ฉ์ธ์ง ์๋ ค์ฃผ์ค ์ ์์ผ์ ๊ฐ์?
๋์์์ ์ฃผ์ ๊ฐ "์ ํ๋ธ ์ธ๋ค์ผ์ AI๋ก ๋ง๋๋ ๋ฐฉ๋ฒ"์ด๋ผ๋ฉด, ์ธ๋ค์ผ ์ ๋ชฉ๋ ์ด๋ฅผ ์ ํํํด์ผ ํ ๊ฒ์ ๋๋ค. ๋ช ๊ฐ์ง ์ ์์ ๋๋ ค๋ณด๊ฒ ์ต๋๋ค:
์ด ์ค์์ ์ด๋ค ์ ๋ชฉ์ด ๋ง์์ ๋์๋์? ์ ํํ์ ์ ๋ชฉ์ ์ธ๋ค์ผ ์ด๋ฏธ์ง์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ฌผ๋ก ์ ๋๋ค. ํ๊ตญ์ด๋ก ๋ช ๊ฐ์ง ์ ์์ ๋๋ ค๋ณด๊ฒ ์ต๋๋ค:
์ด๋ค ์ ๋ชฉ์ด ๋ง์์ ๋์๋์? ์ ํํ์๋ฉด ๊ทธ ์ ๋ชฉ์ ์ธ๋ค์ผ ์ด๋ฏธ์ง์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
์ข์ต๋๋ค! "AI๋ก ๋ ๋๋ํ ์ ํ๋ธ ์ธ๋ค์ผ ๋ง๋ค๊ธฐ"๋ผ๋ ์ ๋ชฉ์ ๋ง์ง๋ง ํ๋ ์์ ์ถ๊ฐํ์ฌ ์ธ๋ค์ผ์ ๋ง๋ค๊ฒ ์ต๋๋ค. ์ ์๋ง ๊ธฐ๋ค๋ ค ์ฃผ์ธ์.
pythonfrom PIL import Image, ImageDraw, ImageFont
# Convert the last frame to a PIL Image
last_frame_pil = Image.fromarray(frames[-1])
# Initialize ImageDraw object
draw = ImageDraw.Draw(last_frame_pil)
# Define font and size
try:
font = ImageFont.truetype("arial.ttf", 50)
except IOError:
font = ImageFont.load_default()
# Define text and position
text = "AI๋ก ๋ ๋๋ํ ์ ํ๋ธ ์ธ๋ค์ผ ๋ง๋ค๊ธฐ"
text_position = (50, 50)
# Add text to image
draw.text(text_position, text, font=font, fill="white")
# Show the modified image
plt.imshow(last_frame_pil)
plt.axis('off')
plt.show()
์ฃ์กํฉ๋๋ค. ํ๊ธ ํ ์คํธ๋ฅผ ์ด๋ฏธ์ง์ ์ถ๊ฐํ๋ ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ค์ ์๋ํ๊ฒ ์ต๋๋ค.
pythonimport cv2
import numpy as np
# Convert the last frame to a format suitable for OpenCV
last_frame_cv = cv2.cvtColor(frames[-1], cv2.COLOR_RGB2BGR)
# Define text and font properties
text = "AI๋ก ๋ ๋๋ํ ์ ํ๋ธ ์ธ๋ค์ผ ๋ง๋ค๊ธฐ"
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 1.5
font_color = (255, 255, 255) # White
font_thickness = 2
# Get the size of the text box
(text_width, text_height), _ = cv2.getTextSize(text, font, font_scale, font_thickness)
# Position to start the text (bottom-left corner)
text_x = 50
text_y = 50 + text_height
# Add text to the image
cv2.putText(last_frame_cv, text, (text_x, text_y), font, font_scale, font_color, font_thickness, lineType=cv2.LINE_AA)
# Convert the OpenCV image to RGB format for displaying in matplotlib
last_frame_rgb = cv2.cvtColor(last_frame_cv, cv2.COLOR_BGR2RGB)
# Show the modified image
plt.imshow(last_frame_rgb)
plt.axis('off')
plt.show()
์์ ์ด๋ฏธ์ง๋ "AI๋ก ๋ ๋๋ํ ์ ํ๋ธ ์ธ๋ค์ผ ๋ง๋ค๊ธฐ"๋ผ๋ ์ ๋ชฉ์ด ์ถ๊ฐ๋ ์ธ๋ค์ผ์ ๋๋ค. ๋ง์กฑํ์๋ฉด ์ด ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ์ฌ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค. ์ ์ฅ์ ์ํ์๋์?
๋ค, ์ ๋ก๋ํ์ ํฐํธ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ดํ์ ์ธ๋ค์ผ ํ๋ฉด ๊ฐ์ด๋ฐ์ ํ์ํ๊ฒ ์ต๋๋ค. ์ ์๋ง ๊ธฐ๋ค๋ ค ์ฃผ์ธ์.
python# Load the custom font
font_path = '/mnt/data/NotoSansKR-Black.ttf'
font_size = 50
font_pil = ImageFont.truetype(font_path, font_size)
# Convert the last frame to a PIL Image
last_frame_pil = Image.fromarray(frames[-1])
# Initialize ImageDraw object
draw = ImageDraw.Draw(last_frame_pil)
# Get the size of the text
text_width, text_height = draw.textsize(text, font=font_pil)
# Calculate X, Y position of the text
text_x = (last_frame_pil.width - text_width) // 2
text_y = (last_frame_pil.height - text_height) // 2
# Add text to image
draw.text((text_x, text_y), text, font=font_pil, fill="white")
# Show the modified image
plt.imshow(last_frame_pil)
plt.axis('off')
plt.show()
์์ ์ด๋ฏธ์ง๋ "AI๋ก ๋ ๋๋ํ ์ ํ๋ธ ์ธ๋ค์ผ ๋ง๋ค๊ธฐ"๋ผ๋ ์ ๋ชฉ์ด ๊ฐ์ด๋ฐ์ ์์นํ ์ธ๋ค์ผ์ ๋๋ค. ์ ๋ก๋ํ์ ํฐํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ํ์์ต๋๋ค. ์ด ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ์๊ฒ ์ต๋๊น?
๋ค, ๊ธ์จ ํฌ๊ธฐ๋ฅผ 4๋ฐฐ๋ก ๋๋ฆฌ๊ณ , "์ ํ๋ธ.." ๋ถํฐ๋ ๋ค์ ์ค์ ๋์ค๊ฒ ํ๋ฉฐ, ํ ์คํธ๋ฅผ ๊ฒ์ ์์ผ๋ก ์ค์ ํ๊ฒ ์ต๋๋ค. ์์ ์ ์งํํ๊ฒ ์ต๋๋ค.
python# Update the font size
new_font_size = font_size * 4
font_pil = ImageFont.truetype(font_path, new_font_size)
# Break the text into two lines
text_line1 = "AI๋ก ๋ ๋๋ํ"
text_line2 = "์ ํ๋ธ ์ธ๋ค์ผ ๋ง๋ค๊ธฐ"
# Get the size of the text for both lines
text_width1, text_height1 = draw.textsize(text_line1, font=font_pil)
text_width2, text_height2 = draw.textsize(text_line2, font=font_pil)
# Calculate the total height
total_text_height = text_height1 + text_height2
# Calculate X, Y position of the text for both lines
text_x1 = (last_frame_pil.width - text_width1) // 2
text_y1 = (last_frame_pil.height - total_text_height) // 2
text_x2 = (last_frame_pil.width - text_width2) // 2
text_y2 = text_y1 + text_height1
# Reinitialize ImageDraw object (to clear previous drawings)
draw = ImageDraw.Draw(last_frame_pil)
# Add text to image for both lines
draw.text((text_x1, text_y1), text_line1, font=font_pil, fill="black")
draw.text((text_x2, text_y2), text_line2, font=font_pil, fill="black")
# Show the modified image
plt.imshow(last_frame_pil)
plt.axis('off')
plt.show()
์์ ์ด๋ฏธ์ง๋ ์์ ๋ ์ธ๋ค์ผ์ ๋๋ค. ๊ธ์จ ํฌ๊ธฐ๋ฅผ 4๋ฐฐ๋ก ๋๋ฆฌ๊ณ , "์ ํ๋ธ.." ๋ถํฐ๋ ๋ค์ ์ค์ ๋์ค๊ฒ ํ์ต๋๋ค. ๋ํ ํ ์คํธ ์์์ ๊ฒ์ ์์ผ๋ก ๋ณ๊ฒฝํ์์ต๋๋ค. ๋ง์กฑํ์๋ฉด ์ด ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ์ ์ฅ์ ์ํ์๋์?
์, ์๊ฒ ์ต๋๋ค. ๊ธฐ์กด์ ํธ์ง๋์ง ์์ ๋ง์ง๋ง ํ๋ ์์ ์๋กญ๊ฒ ํ ์คํธ๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค. ์ ์๋ง ๊ธฐ๋ค๋ ค ์ฃผ์ธ์.
python# Convert the original last frame to a new PIL Image
new_last_frame_pil = Image.fromarray(frames[-1])
# Initialize a new ImageDraw object
new_draw = ImageDraw.Draw(new_last_frame_pil)
# Calculate X, Y position of the text for both lines
text_x1 = (new_last_frame_pil.width - text_width1) // 2
text_y1 = (new_last_frame_pil.height - total_text_height) // 2
text_x2 = (new_last_frame_pil.width - text_width2) // 2
text_y2 = text_y1 + text_height1
# Add text to the new image for both lines
new_draw.text((text_x1, text_y1), text_line1, font=font_pil, fill="black")
new_draw.text((text_x2, text_y2), text_line2, font=font_pil, fill="black")
# Show the modified image
plt.imshow(new_last_frame_pil)
plt.axis('off')
plt.show()
์์ ์ด๋ฏธ์ง๋ ๊ธฐ์กด์ ํธ์ง๋์ง ์์ ๋ง์ง๋ง ํ๋ ์์ ์๋กญ๊ฒ ํ ์คํธ๋ฅผ ์ถ๊ฐํ ์ธ๋ค์ผ์ ๋๋ค. ๋ง์กฑํ์๋ฉด ์ด ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ์ ์ฅ์ ์ํ์๋์?
python# Save the thumbnail image
thumbnail_path = '/mnt/data/youtube_thumbnail_with_text.png'
new_last_frame_pil.save(thumbnail_path)
thumbnail_path
์ธ๋ค์ผ ์ด๋ฏธ์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ ์ฅ๋์์ต๋๋ค. ์ฌ๊ธฐ์์ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ๋์์ ๋๋ฆด ๊ฒ์ด ์์๊น์?
์ ํ๋ธ ์ธ๋ค์ผ์ ๊ถ์ฅ ํฌ๊ธฐ๋ 1280x720 ํฝ์ ์ ๋๋ค. ํ์ฌ ์์ฑ๋ ์ธ๋ค์ผ์ ํฌ๊ธฐ๋ฅผ ํ์ธํ๊ณ ํ์ํ๋ค๋ฉด ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๊ฒ ์ต๋๋ค.
python# Check the dimensions of the current thumbnail image
thumbnail_dimensions = new_last_frame_pil.size
thumbnail_dimensions
ํ์ฌ ์์ฑ๋ ์ธ๋ค์ผ์ ํฌ๊ธฐ๋ 1920x1080 ํฝ์ ์ ๋๋ค. ์ด ํฌ๊ธฐ๋ ์ ํ๋ธ ์ธ๋ค์ผ์ ๊ถ์ฅ ํฌ๊ธฐ์ธ 1280x720 ํฝ์ ๋ณด๋ค ํฝ๋๋ค. ๋ฐ๋ผ์ ํ์ฌ ํฌ๊ธฐ๋ก๋ ๋ฌธ์ ์์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ํ์ ๋ค๋ฉด 1280x720 ํฝ์ ๋ก ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์๋ ์์ต๋๋ค. ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ์๊ฒ ์ต๋๊น?
python# Resize the thumbnail image to 1280x720 pixels
recommended_size = (1280, 720)
resized_thumbnail = new_last_frame_pil.resize(recommended_size, Image.ANTIALIAS)
# Save the resized thumbnail image
resized_thumbnail_path = '/mnt/data/resized_youtube_thumbnail_with_text.png'
resized_thumbnail.save(resized_thumbnail_path)
# Show the resized image
plt.imshow(resized_thumbnail)
plt.axis('off')
plt.show()
resized_thumbnail_path
์ธ๋ค์ผ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ฅผ 1280x720 ํฝ์ ๋ก ์กฐ์ ํ์์ต๋๋ค. ์ฌ๊ธฐ์์ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค.
๋ ๋์๋๋ฆด ๊ฒ์ด ์์๊น์?
๋ค, ์ ํ๋ธ ์์์ ์ ๋ชฉ, ์ค๋ช , ๊ทธ๋ฆฌ๊ณ ํด์ํ๊ทธ๋ฅผ ์์ฑํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
"AI์ ํจ๊ปํ๋ ์ ํ๋ธ ์ธ๋ค์ผ ์ ์: ์ค์๊ฐ ํํ ๋ฆฌ์ผ"
์๋ ํ์ธ์, ์ฌ๋ฌ๋ถ! ์ด๋ฒ ์์์์๋ OpenAI์ GPT-4๋ฅผ ํ์ฉํ์ฌ ์ ํ๋ธ ์ธ๋ค์ผ์ ์ด๋ป๊ฒ ๋ง๋๋์ง ๋ณด์ฌ๋๋ฆด ๊ฒ์ ๋๋ค.
๐ฅ ์ด ์์์์ ๋ค๋ฃฐ ์ฃผ์ ๋ด์ฉ
๐ ์ด ํํ ๋ฆฌ์ผ์ ํตํด ์ธ๋ค์ผ ์ ์์ ๋ ํจ์จ์ ์ด๊ณ ์ฝ๊ฒ ํ ์ ์์ต๋๋ค.
๐ ์ฌ์ฉ๋ ๋๊ตฌ
๐ฃ ๊ด๋ จ ๋งํฌ
โ ๊ตฌ๋ ๊ณผ ์ข์์ ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์!
#AI์ธ๋ค์ผ #์ ํ๋ธ์ธ๋ค์ผ #OpenAIGPT4 #Pythonํํ ๋ฆฌ์ผ #์ธ๋ค์ผ์ ์ #์ ํ๋ธ๋ง์ผํ #์ ํ๋ธ์์ #์ธ๋ค์ผ๋์์ธ #PIL
์ด ๋ด์ฉ์ด ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค! ํ์ํ๋ค๋ฉด ๋ด์ฉ์ ์์ ํ๊ฑฐ๋ ์ถ๊ฐํ ์ ์์ต๋๋ค.
์๊ฒ ์ต๋๋ค, ์ด๊ทธ๋ก๋ฅผ ๋ ์ ์๋ ์ ๋ชฉ์ ๋ช ๊ฐ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
์ด๋ค ์ ๋ชฉ์ด ๋ง์์ ๋์๋์? ์๋๋ฉด ๋ค๋ฅธ ์์ด๋์ด๊ฐ ์์ผ์ ๊ฐ์?
๊ฐ์ฌํฉ๋๋ค! "์กฐํ์ ๋ฎ์์? AI๋ก ์ธ๋ค์ผ์ ๋ฐ๊พธ๋ฉด ๋ค๋ฅด๋ค!"๋ผ๋ ์ ๋ชฉ์ ์กฐํ์๋ฅผ ๋์ด๊ณ ์ ํ๋ ์ ํ๋ฒ๋ค์๊ฒ ๋งค์ฐ ํจ๊ณผ์ ์ผ ๊ฒ์ผ๋ก ์๊ฐ๋ฉ๋๋ค. ์ข์ ์ธ๋ค์ผ์ ์ค์ ๋ก ์์์ ์กฐํ์์ ์ฐธ์ฌ๋๋ฅผ ๋์ผ ์ ์์ผ๋, ์ด ์ฃผ์ ๋ ๋ง์ ์ฌ๋๋ค์๊ฒ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
์ ๋ชฉ๊ณผ ์ค๋ช , ํด์ํ๊ทธ๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ข์ ํจ๊ณผ๋ฅผ ๋ณผ ์ ์์ ๊ฒ์ผ๋ก ๊ธฐ๋๋ฉ๋๋ค. ์ถ๊ฐ๋ก ๋์๋๋ฆด ๊ฒ์ด ์์๊น์?
๋ค, ์๊ฒ ์ต๋๋ค! ๋ง์ฝ ๋์ค์ ๋ ๋์์ด ํ์ํ์๋ฉด ์ธ์ ๋ ์ง ๋์์ ์ฃผ์ธ์. ์ข์ ํ๋ฃจ ๋ณด๋ด์๊ณ , ์์ ์ ์์ ๋ง์ ์ฑ๊ณต์ ๋ฐ๋๋๋ค! ๐